package com.xb.cloud.order.service.impl;

import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import com.xb.cloud.common.constant.DbConstants;
import com.xb.cloud.common.util.BeanUtils;
import com.xb.cloud.common.util.StringUtils;
import com.xb.cloud.order.model.ProductStock;
import com.xb.cloud.order.model.So;
import com.xb.cloud.order.model.SoExample;
import com.xb.cloud.order.model.SoExample.Criteria;
import com.xb.cloud.order.model.SoSku;
import com.xb.cloud.order.model.mapper.ProductStockMapper;
import com.xb.cloud.order.model.mapper.SellOrderMapper;
import com.xb.cloud.order.model.mapper.SoMapper;
import com.xb.cloud.order.model.mapper.SoSkuMapper;
import com.xb.cloud.order.service.client.ProductStockService;
import com.xb.cloud.order.service.client.SellOrderMerchantService;
import com.xb.cloud.order.service.client.SellOrderSkuService;
import com.xb.cloud.order.service.client.bo.OrderQueryMerchantBo;
import com.xb.cloud.order.service.client.bo.SellOrderBo;
import com.xb.cloud.order.service.client.bo.SellOrderItemBo;
import com.xb.cloud.order.service.client.bo.SoSkuSummeryBo;
import com.xb.cloud.product.merchant.service.client.bo.EndMerchantUserBo;
import com.xb.cloud.service.client.ServiceReturnCodes;
import com.xb.cloud.service.client.ServiceReturnInfo;
import com.xb.cloud.service.client.ServiceReturnUtils;
import com.xb.cloud.user.service.client.EndUserService;
import com.xb.cloud.user.service.client.bo.EndUserBo;

/**
 * 商家端订单管理service;
 * 
 * @author kexue
 *
 */
@Service
public class SellOrderMerchantServiceImpl extends AbstractService implements SellOrderMerchantService {

	@Resource
	SoMapper soMapper;

	@Resource
	SellOrderMapper sellOrderMapper;

	@Resource
	SoSkuMapper soSkuMapper;

	@Resource
	ProductStockMapper productStockMapper;

	@Resource
	EndUserService endUserService;

	@Resource
	SellOrderSkuService sellOrderSkuService;

	@Resource
	ProductStockService productStockService;

	private static final Logger LOGGER = LoggerFactory.getLogger(SellOrderMerchantServiceImpl.class);

	/**
	 * 按照店铺+状态查询某一种状态的订单数量
	 */
	@Override
	public ServiceReturnInfo countOrderByShopAndStatus(OrderQueryMerchantBo orderQueryMerchantBo) {
		SoExample example = new SoExample();
		Criteria criteria = example.createCriteria().andCompanyIdEqualTo(orderQueryMerchantBo.getCompanyId())
				.andShopIdEqualTo(orderQueryMerchantBo.getShopId()).andIsLeafEqualTo(DbConstants.TRUE)
				.andIsUserDeletedEqualTo(DbConstants.FALSE);
		if (orderQueryMerchantBo.getStatus() != null) {
			criteria.andSoStatusEqualTo(orderQueryMerchantBo.getStatus());
		}
		if (orderQueryMerchantBo.getStartTime() != null && orderQueryMerchantBo.getEndTime() != null) {

			criteria.andCreateTimeBetween(orderQueryMerchantBo.getStartTime(), orderQueryMerchantBo.getEndTime());
		}
		return ServiceReturnUtils.success(soMapper.countByExample(example));
	}

	/**
	 * 按照店铺+状态查询某一种状态的订单数量
	 */
	@Override
	public ServiceReturnInfo getOrderListByShopAndStatus(OrderQueryMerchantBo orderQueryMerchantBo) {
		SoExample example = new SoExample();
		example.setStartPage(orderQueryMerchantBo.getStartPage());
		example.setPageSize(orderQueryMerchantBo.getPageSize());
		// 查询用户子订单，父订单用于统计等
		Criteria criteria = example.createCriteria().andCompanyIdEqualTo(orderQueryMerchantBo.getCompanyId())
				.andShopIdEqualTo(orderQueryMerchantBo.getShopId()).andIsLeafEqualTo(DbConstants.TRUE)
				.andIsUserDeletedEqualTo(DbConstants.FALSE);
		if (orderQueryMerchantBo.getStatus() != null) {
			criteria.andSoStatusEqualTo(orderQueryMerchantBo.getStatus());
		}
		if (orderQueryMerchantBo.getStartTime() != null && orderQueryMerchantBo.getEndTime() != null) {

			criteria.andCreateTimeBetween(orderQueryMerchantBo.getStartTime(), orderQueryMerchantBo.getEndTime());
		}
		example.setOrderByClause(" create_time desc, update_time desc");
		return ServiceReturnUtils.success(sellOrderMapper.selectOrderList(example));
	}

	/**
	 * 统计不同状态下的订单数量.
	 * 
	 * @param orderQueryMerchantBo
	 * @return
	 */
	@Override
	public ServiceReturnInfo getOrderCountStatistic(OrderQueryMerchantBo orderQueryMerchantBo) {
		SoExample example = new SoExample();
		Criteria criteria = example.createCriteria().andCompanyIdEqualTo(orderQueryMerchantBo.getCompanyId())
				.andShopIdEqualTo(orderQueryMerchantBo.getShopId()).andIsLeafEqualTo(DbConstants.TRUE)
				.andIsUserDeletedEqualTo(DbConstants.FALSE);

		if (orderQueryMerchantBo.getStatus() != null) {
			criteria.andSoStatusEqualTo(orderQueryMerchantBo.getStatus());
		}

		List<Map<String, Object>> orderCountWithStatus = soMapper.getOrderCountWithStatus(example);
		Map<Integer, Integer> resultMap = new HashMap<>();
		if (orderCountWithStatus != null) {
			for (Map<String, Object> map : orderCountWithStatus) {
				Long count = (Long) map.get("count");
				Integer status = (Integer) map.get("status");
				resultMap.put(status, count.intValue());
			}
		}
		return ServiceReturnUtils.success(resultMap);
	}

	/**
	 * 确认支付(商家端)
	 * 
	 * @param orderQueryMerchantBo
	 * @param endMerchantUserBo
	 * @return
	 */
	@Override
	public ServiceReturnInfo confirmPay(Long orderId, EndMerchantUserBo endMerchantUserBo) {
		SoExample soExample = new SoExample();
		Criteria criteria = soExample.createCriteria().andIsLeafEqualTo(DbConstants.TRUE)
				.andIsUserDeletedEqualTo(DbConstants.FALSE).andIdEqualTo(orderId);
		List<So> soList = soMapper.selectByExample(soExample);
		if (soList == null || soList.size() == 0) {
			return ServiceReturnUtils.error(ServiceReturnCodes.ORDER_NOT_EXIST);
		} else {
			So so = soList.get(0);
			if (so.getSoStatus().intValue() != DbConstants.SO_STATUS_AWAITE_PAY) {
				// 状态不是待支付
				return ServiceReturnUtils.error(ServiceReturnCodes.ORDER_STATUS_INVALID);
			} else {

				So record = new So();
				record.setSoStatus(DbConstants.SO_STATUS_ALREADY_PAY); // 更新为：已支付
				record.setPaymentType(DbConstants.ORDER_PAYMENT_TYPE_OFFLINE);// 更新：线下支付
				Date now = timeService.getDate();
				record.setUpdateTime(now);
				record.setPaymentConfirmTime(now);
				criteria.andSoStatusEqualTo(DbConstants.SO_STATUS_AWAITE_PAY);
				int updateRow = soMapper.updateByExampleSelective(record, soExample);
				if (updateRow > 0) {
					return ServiceReturnUtils.success();
				} else {
					return ServiceReturnUtils.error(ServiceReturnCodes.ORDER_UPDATE_FAILED); // 更新失败
				}
			}
		}

	}

	/**
	 * 发货(商家端)
	 * 
	 * @param orderQueryMerchantBo
	 * @return
	 */
	@Transactional(value = "transactionManager_order")
	public ServiceReturnInfo orderDelivery(Long orderId, EndMerchantUserBo endMerchantUserBo) {
		// 待更新的sku列表返回

		SoExample soExample = new SoExample();
		Criteria criteria = soExample.createCriteria().andIsLeafEqualTo(DbConstants.TRUE)
				.andIsUserDeletedEqualTo(DbConstants.FALSE).andIdEqualTo(orderId);
		List<So> soList = soMapper.selectByExample(soExample);
		if (soList == null || soList.size() == 0) {
			return ServiceReturnUtils.error(ServiceReturnCodes.ORDER_NOT_EXIST);
		} else {
			So so = soList.get(0);
			if (so.getSoStatus().intValue() != DbConstants.SO_STATUS_ALREADY_PAY) {
				// 状态不是已支付。
				return ServiceReturnUtils.error(ServiceReturnCodes.ORDER_STATUS_INVALID);
			} else {

				Date now = timeService.getDate();
				So record = new So();
				record.setSoStatus(DbConstants.SO_STATUS_ALREADY_COMPLETED); // 更新为：已完成
				record.setUpdateTime(now);
				record.setDeliveryTime(now);

				criteria.andSoStatusIn(Arrays.asList(new Integer[] { DbConstants.SO_STATUS_ALREADY_PAY }));
				int updateRow = soMapper.updateByExampleSelective(record, soExample);
				if (updateRow > 0) {
					// 更新库存 : 冻结库存-- && 实际库存--;
					List<SoSkuSummeryBo> sellOrderSkuBoList = sellOrderSkuService.getOrderSkuListByOrderId(orderId);
					LOGGER.info("更新订单:" + orderId + ",到状态:确认收货");
					ServiceReturnInfo returnInfo = productStockService.updateStockForMerchant(sellOrderSkuBoList,
							DbConstants.DEFAULT_WAREHOUSE_ID, DbConstants.SO_STATUS_ALREADY_COMPLETED,
							endMerchantUserBo);

					if (ServiceReturnUtils.isSuccess(returnInfo)) {
						return ServiceReturnUtils.success(sellOrderSkuBoList);
					} else {
						String msg = "库存更新失败,发货失败";
						LOGGER.error(msg);
						throw new RuntimeException(msg);
					}
				} else {
					String msg = "订单状态更新失败，发货失败";
					LOGGER.error(msg);
					throw new RuntimeException(msg);
				}
			}
		}
	}

	/**
	 * 取消(商家端)
	 * 
	 * @param orderQueryMerchantBo
	 * @return
	 */
	@Override
	@Transactional(value = "transactionManager_order")
	public ServiceReturnInfo orderCancel(Long orderId, EndMerchantUserBo endMerchantUserBo, Long cancelReasonId) {

		SoExample soExample = new SoExample();
		Criteria criteria = soExample.createCriteria().andIsLeafEqualTo(DbConstants.TRUE)
				.andIsUserDeletedEqualTo(DbConstants.FALSE).andIdEqualTo(orderId);
		List<So> soList = soMapper.selectByExample(soExample);
		if (soList == null || soList.size() == 0) {
			return ServiceReturnUtils.error(ServiceReturnCodes.ORDER_NOT_EXIST);
		} else {
			So so = soList.get(0);
			if (!(so.getSoStatus().intValue() == DbConstants.SO_STATUS_AWAITE_PAY
					|| so.getSoStatus().intValue() == DbConstants.SO_STATUS_ALREADY_PAY)) {
				// 状态不是待支付或者已支付 。
				return ServiceReturnUtils.error(ServiceReturnCodes.ORDER_STATUS_INVALID);
			} else {

				Date currentDate = timeService.getDate();
				So record = new So();
				record.setSoStatus(DbConstants.SO_STATUS_ALREADY_CANCEL); // 更新为：已取消
				record.setUpdateTime(currentDate);
				record.setCancelReasonId(cancelReasonId);
				record.setCancelCsId(endMerchantUserBo.getId());// 设置取消相关的数据
				record.setCancelCsName(endMerchantUserBo.getLoginName());
				record.setCancelTime(currentDate);

				criteria.andSoStatusIn(Arrays
						.asList(new Integer[] { DbConstants.SO_STATUS_AWAITE_PAY, DbConstants.SO_STATUS_ALREADY_PAY }));
				int updateRow = soMapper.updateByExampleSelective(record, soExample);
				if (updateRow > 0) {
					// 更新库存 : 冻结库存-- && 实际库存--;
					LOGGER.info("更新订单:" + orderId + ",到状态:取消");
					List<SoSkuSummeryBo> sellOrderSkuBoList = sellOrderSkuService.getOrderSkuListByOrderId(orderId);
					ServiceReturnInfo returnInfo = productStockService.updateStockForMerchant(sellOrderSkuBoList,
							DbConstants.DEFAULT_WAREHOUSE_ID, DbConstants.SO_STATUS_ALREADY_CANCEL, endMerchantUserBo);

					if (ServiceReturnUtils.isSuccess(returnInfo)) {
						return ServiceReturnUtils.success();
					} else {
						String msg = "库存更新失败,取消订单失败";
						LOGGER.error(msg);
						throw new RuntimeException(msg);
					}
				} else {
					String msg = "订单状态更新失败，取消订单失败";
					LOGGER.error(msg);
					throw new RuntimeException(msg);
				}
			}
		}
	}

	@Override
	@Transactional(value = "transactionManager_order", propagation = Propagation.REQUIRED)
	public ServiceReturnInfo generateOrder(SellOrderBo sellOrderBo) {
		Date currentTime = timeService.getDate();

		// 客户电话
		String goodReceiverPhone = sellOrderBo.getGoodReceiverPhone();
		if (!StringUtils.isBlank(goodReceiverPhone)) {
			// 判断是否是系统终端用户，如果不存在创建用户
			ServiceReturnInfo returnInfo = endUserService.getEndUserByPhoneNum(sellOrderBo.getCompanyId(),
					goodReceiverPhone);
			if (ServiceReturnUtils.isError(returnInfo)) {
				return returnInfo;
			}

			if (returnInfo.getData() == null) {
				// 创建新用户
				EndUserBo endUserBO = new EndUserBo();
				endUserBO.setCompanyId(sellOrderBo.getCompanyId());
				endUserBO.setId(ipKeyGenerator.generateKey());
				endUserBO.setCreateTime(currentTime);
				endUserBO.setPhoneNum(goodReceiverPhone);
				endUserBO.setEndUserRealName(sellOrderBo.getGoodReceiverName());
				endUserBO.setEndUserNickName(sellOrderBo.getGoodReceiverName());
				endUserBO.setEndUserLastBoughtDate(currentTime);
				returnInfo = endUserService.createEndUser(endUserBO);
				if (ServiceReturnUtils.isError(returnInfo)) {
					return returnInfo;
				}
				sellOrderBo.setEndUserId(endUserBO.getId());
			} else {
				EndUserBo endUser = (EndUserBo) returnInfo.getData();
				sellOrderBo.setEndUserId(endUser.getId());
			}

		} else {
			LOGGER.error("代客下单未填写手机号，so.enduserId=0");
			sellOrderBo.setEndUserId(0L);// 不存在用户
		}

		sellOrderBo.setId(ipKeyGenerator.generateKey());
		sellOrderBo.setCreateTime(currentTime);
		So sellOrder = BeanUtils.newAndCopyProperties(So.class, sellOrderBo);
		soMapper.insertSelective(sellOrder);

		List<SellOrderItemBo> items = sellOrderBo.getItems();
		for (SellOrderItemBo sellOrderItemBo : items) {
			SoSku orderSku = BeanUtils.newAndCopyProperties(SoSku.class, sellOrderItemBo);
			orderSku.setId(ipKeyGenerator.generateKey());
			orderSku.setEndUserId(0L);// 不存在用户
			orderSku.setCreateTime(currentTime);
			orderSku.setSoId(sellOrder.getId());
			soSkuMapper.insertSelective(orderSku);

			ProductStock productStock = new ProductStock();
			productStock.setCompanyId(orderSku.getCompanyId());
			productStock.setShopId(orderSku.getShopId());
			productStock.setProductId(orderSku.getProductId());
			productStock.setRealFrozenStockNum(Long.valueOf(orderSku.getSkuNum()));
			productStock.setUpdateTime(currentTime);
			int updateSkuStock = productStockMapper.updateSkuStock(productStock);//
			if (updateSkuStock <= 0) {
				LOGGER.error("代客下单库存更新失败：productId:{},num:{}", productStock.getProductId(),
						productStock.getRealFrozenStockNum());

				TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
			}

		}

		return ServiceReturnUtils.success(sellOrderBo);
	}

}
